package internal

import (
	"fmt"
	"sort"

	"github.com/globalsign/mgo/bson"
	log "github.com/sirupsen/logrus"

	"GameServer/Common/data"
	"GameServer/Common/utils"
	"GameServer/Game/activity"
	"GameServer/Game/dbmodule"
	"GameServer/Game/errors"
	"GameServer/Game/lib"
	"GameServer/Game/m"
	"GameServer/Game/timer"

	"GameServer/globalFunc"
)

var (
	tableName string = "userActRanks"
)

// 重新分组时用的缓存结构
type PointData struct {
	Uid       string
	User      *m.User
	Point     int64
	ItemCount int64
}

// 所有分组排名
type ActRankManager struct {
	RankGroups map[int64]*m.ActRankGroup //
}

func StringToBsonObjectId(str string) (b bson.ObjectId) {
	return bson.ObjectIdHex(str)
}

func NewActRankManager() *ActRankManager {
	return &ActRankManager{
		RankGroups: make(map[int64]*m.ActRankGroup, 0),
	}
}

func (arm *ActRankManager) Init() {
	// 使用的是game/m/activity_rank.go的数据库
	listAccept := make([]*m.ActRankGroup, 0)
	err := dbmodule.MgoDB.GameDB.FindAll(tableName, nil, nil, &listAccept)
	if err != nil {
		return
	}
	if arm.RankGroups == nil {
		arm.RankGroups = make(map[int64]*m.ActRankGroup, 0)
	}
	if len(listAccept) > 0 {
		lastActId := int64(0)
		for _, actRankGroup := range listAccept {
			var groupId int64 = actRankGroup.GroupId
			// 还原到缓存
			m.Cache.Put(tableName, actRankGroup.GroupId, actRankGroup)
			// 还原到上层结构
			arm.RankGroups[groupId] = actRankGroup
			lastActId = actRankGroup.ActId
		}
		rankactId, _, err := activity.ActivityModule.GetRankActId() //获取当前排名活动Id
		fmt.Printf("当前老虎机排名活动id: %d,缓存记录排名id : %d \n", rankactId, lastActId)
		if err != nil || rankactId == -1 || lastActId != rankactId {
			// 删除数据库旧的分组数据
			fmt.Printf("Init删除数据库旧的分组数据,rankActId = %d,lastActId = %d \n", rankactId, lastActId)
			var GroupIndex int64 = 1
			for {
				arG := m.GetActRankGroupByGroupId(GroupIndex)
				uparG, find := arm.RankGroups[GroupIndex]
				if uparG != nil || find {
					delete(arm.RankGroups, GroupIndex)
				}
				if arG != nil {
					arG.Delete() // 数据库删除数据
					GroupIndex = (GroupIndex + 1)
				} else {
					break
				}
			}
		}
		if err == nil && rankactId != -1 && lastActId != rankactId {
			// 检查排名奖励是否有漏发
			//arm.CheckActRankingRewardIsSend()
			// 执行重新分组
			arm.ReGroupActRank()
		}
	} else {
		// 如果数据库没有数据，判断为第一次开启活动
		// 检查排名奖励是否有漏发
		//arm.CheckActRankingRewardIsSend()
		// 第一次开活动，就不检测是否漏发奖励了
		arm.ReGroupActRank()
	}
	// 每小时执行--更新分组中机器人的道具数量
	timer.AddFunc("@every 1h", func() {
		// 获取当前排名活动Id
		rankActId, _, err := activity.ActivityModule.GetRankActId()
		if err != nil {
			return
		}
		// 当前排名活动失效，不执行
		if lib.IsActActivityInActTimeByActId(rankActId) == false {
			return
		}
		listAccept := make([]*m.ActRankGroup, 0)
		err = dbmodule.MgoDB.GameDB.FindAll(tableName, nil, nil, &listAccept)
		if err != nil {
			return
		}
		if len(listAccept) > 0 {
			actTurn, _ := lib.GetActTurn(rankActId)
			//
			if arm.RankGroups == nil {
				arm.RankGroups = make(map[int64]*m.ActRankGroup, 0)
			}
			for _, actRankGroup := range listAccept {
				var groupId int64 = actRankGroup.GroupId
				// 还原到上层结构
				arm.RankGroups[groupId] = actRankGroup
				// actRankGroup.RobotAutoAdd()
				actRankGroup.RobotAutoAdd_ByTurn(actTurn)
			}

			fmt.Println("活动机器人添加道具time:", utils.TimeToLayout(utils.TNow()))
		}
	})
}

func (arm *ActRankManager) CheckActRankingRewardIsSend() {
	nowTimeStamp := utils.TNow().Unix()
	if arm.RankGroups != nil && len(arm.RankGroups) > 0 {
		for groupId, rankData := range arm.RankGroups {
			activId := rankData.ActId
			//读表
			tpl, ok := data.Get("ActActivities", uint64(activId))
			if !ok {
				err := errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到激活活动配置,id = %d", activId))
				log.WithFields(log.Fields{
					"err":     err.Error(),
					"method":  "GetActActivityList",
					"activId": activId,
				}).Debug(fmt.Sprintf("没有找到激活活动配置,id = %d", activId))
				continue
			}
			actBeginTime, err := utils.LayoutToTime(tpl.(data.ActActivity).BeginTime)
			if err != nil {
				continue
			}
			actEndTime, err := utils.LayoutToTime(tpl.(data.ActActivity).EndTime)
			if err != nil {
				continue
			}
			actBeginTimeStamp := actBeginTime.AddDate(0, 0, 1).Unix()
			actEndTimeStamp := actEndTime.AddDate(0, 0, 1).Unix()
			var checkingTimeStamp int64 = actBeginTimeStamp
			var isReSendRewards bool = false
			for {
				if checkingTimeStamp > actEndTimeStamp || checkingTimeStamp > nowTimeStamp {
					break
				}
				if rankData.SendRewardTimeStamp == nil {
					rankData.SendRewardTimeStamp = make(map[int64]int64, 0)
				}
				_, ok := rankData.SendRewardTimeStamp[checkingTimeStamp]
				if ok == false {
					fmt.Printf("actId[%d]group[%d]找不到[%d][%s]的老虎机排行榜派奖记录，将重新派奖\n", activId, groupId, checkingTimeStamp, utils.TTime(checkingTimeStamp, 0))
				}
				checkingTimeStamp = checkingTimeStamp + 86400
			}
			if isReSendRewards {
				// 还原到缓存
				m.Cache.Put(tableName, groupId, rankData)
				// 还原到上层结构
				arm.RankGroups[groupId] = rankData
			}
		}
	} else {
		log.WithFields(log.Fields{
			"method": "CheckActRankingRewardIsSend",
		}).Debug("老虎机活动，检测活动排行奖励漏发，无排名数据不检测")
	}
}

func (arm *ActRankManager) Run(closeSig chan bool) {

}

func (arm *ActRankManager) Destroy() {

}

// 活动排名重新分组
func (arm *ActRankManager) ReGroupActRank() {
	lastActId := int64(0)
	// 不能直接从这个模块中获取，若活动不是在服务器开启时开放，此时新增的小组是在缓存中，没有同步到该模块
	// if arm.RankGroups != nil && len(arm.RankGroups) > 0 {
	// 	for _, rankG := range arm.RankGroups {
	// 		lastActId = rankG.ActId
	// 		break
	// 	}
	// }
	listAccept := make([]*m.ActRankGroup, 0)
	err := dbmodule.MgoDB.GameDB.FindAll(tableName, nil, nil, &listAccept)
	if err == nil {
		if len(listAccept) > 0 {
			lastActId = listAccept[0].ActId
		}
	}
	//重新构建--清空map
	arm.RankGroups = make(map[int64]*m.ActRankGroup)
	//获取当前排名活动Id
	rankActId, rankRewardId, err := activity.ActivityModule.GetRankActId()
	// 没有活动，或者活动ID不一致，删除分组数据
	if err != nil || rankActId == -1 || lastActId != rankActId {
		// 删除数据库旧的分组数据
		fmt.Printf("删除数据库旧的分组数据.rankActid = %d,lastActId = %d\n", rankActId, lastActId)
		var GroupIndex int64 = 1
		for {
			arG := m.GetActRankGroupByGroupId(GroupIndex)
			uparG, find := arm.RankGroups[GroupIndex]
			if uparG != nil || find {
				delete(arm.RankGroups, GroupIndex)
			}
			if arG != nil {
				arG.Delete() // 数据库删除数据
				GroupIndex = (GroupIndex + 1)
			} else {
				break
			}
		}
	}
	// if lastActId != rankActId {
	// 	fmt.Printf("上次排名ID[%d]，本次排名id[%d],不一致", lastActId, rankActId)
	// } else {
	// 	fmt.Printf("上次排名ID[%d]，本次排名id[%d]", lastActId, rankActId)
	// }
	// 没有活动不执行分组
	if err != nil || rankActId == -1 {
		return
	}
	fmt.Println("排名活动,id:", rankActId)
	//----Func---UserPoint---
	CalculateUserPoint := func(u *m.User, ItemCount int64) (point int64) {
		// 条件物料获取
		nowT := utils.TNow().Unix()
		point = 0
		point = (point + (u.SlotLv * 10)) // 基准分是老虎机等级的10倍
		// 一天的时间戳是86400
		var loginOffset int64 = (nowT - u.LastLoginTime)
		if loginOffset < 86400 {
			point = (point + 10) // 基本等于每天登陆的玩家，增加10关卡的积分
		} else if loginOffset < (86400 * 3) {
			point = (point + 5) // 3天内有登陆的玩家，增加5关卡积分
		}
		point = (point + ItemCount) // 最后加上累计获得的道具数量
		return point
	}
	//----Func---FindGroup---
	FindGroup := func(point int64, GroupId int64) (groupInfo *m.ActRankGroup) {
		// 查询组--这里只保存上层结构，外部调用Update
		_, findGroup := arm.RankGroups[GroupId]
		if findGroup == false {
			newGroup := &m.ActRankGroup{
				GroupId:          GroupId,
				UserActRankGroup: make(map[string]*m.UserActRank, 0),
			}
			arm.RankGroups[GroupId] = newGroup
			return newGroup
		} else {
			if len(arm.RankGroups[GroupId].UserActRankGroup) < 30 {
				return arm.RankGroups[GroupId]
			} else {
				var newGroupId int64 = (GroupId + 1)
				newGroup := &m.ActRankGroup{
					GroupId:          newGroupId,
					UserActRankGroup: make(map[string]*m.UserActRank, 0),
				}
				arm.RankGroups[newGroupId] = newGroup
				return newGroup
			}
		}
	}
	//----End---

	offLine7DayUnix := utils.TNow().Unix() - 86400*7
	// 找出7天未登录过的玩家
	noUsers := make([]*m.User, 0)
	dbmodule.MgoDB.GameDB.FindAll("user", bson.M{"last_login_time": bson.M{"$lt": offLine7DayUnix}}, nil, &noUsers)
	// 保证数组里面至少40个用户，防止填充失败
	for noLen := len(noUsers); noLen < 40; noLen++ {
		noUsers = append(noUsers, &m.User{
			Name:        fmt.Sprintf("%s", utils.GenName()),
			Head:        fmt.Sprintf("%s", utils.GenDefaultHead()),
			AvatarFrame: data.AvatarFrameEnum.DefaultFrame,
		})
	}

	// 找出7天内登录过的玩家
	activeUsers := make([]*m.User, 0)
	dberr := dbmodule.MgoDB.GameDB.FindAll("user", bson.M{"last_login_time": bson.M{"$gte": offLine7DayUnix}}, nil, &activeUsers)
	if dberr != nil || len(activeUsers) == 0 {
		log.WithFields(log.Fields{
			"method": "ReGroupActRank",
			"err":    dberr,
		}).Error("获取用户数据失败，或数据长度为0")
		return
	}

	// 先评分，根据用户老虎机登记，和活跃度，给玩家分组
	UserPoint := make([]*PointData, 0)
	for _, user := range activeUsers {
		// 进度
		var totalItemCount int64 = 0
		theUser, ok := globalFunc.GetUserByUID(user.Uid.Hex())
		if ok {
			rankProgress, _ := lib.GetOrCreateActProgress(theUser, rankActId)
			if rankProgress != nil {
				totalItemCount = rankProgress.TotalItemCount
			}
			//评分
			point := CalculateUserPoint(user, totalItemCount)
			newPointData := &PointData{
				Uid:       theUser.Uid.Hex(),
				User:      theUser,
				Point:     point,
				ItemCount: totalItemCount,
			}
			// fmt.Printf("活动[%d]玩家 [%s] 活动道具 [%d] \n", rankActId, user.Name, totalItemCount)
			if lastActId != rankActId {
				newPointData.ItemCount = 0
				// fmt.Printf("活动ID不一致，ItemCount重置为0 \n")
			}
			UserPoint = append(UserPoint, newPointData)
		}
	}
	// 对分数进行排序
	sort.Slice(UserPoint, func(i, j int) bool {
		return UserPoint[i].Point > UserPoint[j].Point
	})
	// 后分组
	var GroupIndex int64 = 1 // 分组从1索引开始，0是默认值，用于标识新用户
	for _, pData := range UserPoint {
		group := FindGroup(pData.Point, GroupIndex)
		//pData.User.ChangeUserGroup(group.GroupId)
		globalFunc.ChangeUserSlotActRankGroup(pData.User.Uid.Hex(), group.GroupId)
		// 填写配置--GroupId已在FindGroup赋值
		group.ActId = rankActId
		group.RewardId = rankRewardId
		group.HasRobot = 1
		// 新增成员
		group.AddMember(&m.UserActRank{
			Uid:         pData.Uid,
			Name:        pData.User.Name,
			Head:        pData.User.Head,
			AvatarFrame: pData.User.AvatarFrame,
			Item:        0,
			LastRankId:  0,
			RankId:      0,
			IsRobot:     1,
		})
		group.Update(group)
		arm.RankGroups[group.GroupId] = group
		//记录当前组的ID，给下次FindGroup搜索
		GroupIndex = group.GroupId
	}

	noIdx := 0
	noLen := len(noUsers)
	// 获取当前活动第几轮
	// actTurn, _ := lib.GetActTurn(rankActId)
	// 给所有分组增加机器人，30人组添加10个机器人，不满30分组的添加满机器人
	for id := int64(1); id <= GroupIndex; id++ {
		group, _ := arm.RankGroups[id]
		num := 40 - len(group.UserActRankGroup)
		if noIdx+num > noLen {
			noIdx = 0
		}
		// 填充机器人
		group.TryFillUpMemberWithRobot(1, 0, noUsers[noIdx:noIdx+num])
		arm.RankGroups[group.GroupId] = group
		noIdx += num
	}

	// 删除数据库旧的分组数据
	GroupIndex = (GroupIndex + 1)
	for {
		arG := m.GetActRankGroupByGroupId(GroupIndex)
		uparG, find := arm.RankGroups[GroupIndex]
		if uparG != nil || find {
			delete(arm.RankGroups, GroupIndex)
		}
		if arG != nil {
			arG.Delete() // 数据库删除数据
			GroupIndex = (GroupIndex + 1)
		} else {
			break
		}
	}
	// 通知每个分组，自行排序
	for _, g := range arm.RankGroups {
		g.ReSort("")
	}
}

// 活动排名重新分组
// func (arm *ActRankManager) ReGroupActRank_ForGmTest(lastActId int64) {
// 	// lastActId := int64(0)
// 	// if arm.RankGroups != nil && len(arm.RankGroups) > 0 {
// 	// 	for _, rankG := range arm.RankGroups {
// 	// 		lastActId = rankG.ActId
// 	// 		break
// 	// 	}
// 	// }
// 	//重新构建--清空map
// 	arm.RankGroups = make(map[int64]*m.ActRankGroup)
// 	//获取当前排名活动Id
// 	rankActId, rankRewardId, err := activity.ActivityModule.GetRankActId()
// 	// 没有活动，或者活动ID不一致，删除分组数据
// 	if err != nil || rankActId == -1 || lastActId != rankActId {
// 		// 删除数据库旧的分组数据
// 		fmt.Println("删除数据库旧的分组数据")
// 		var GroupIndex int64 = 1
// 		for {
// 			arG := m.GetActRankGroupByGroupId(GroupIndex)
// 			uparG, find := arm.RankGroups[GroupIndex]
// 			if uparG != nil || find {
// 				delete(arm.RankGroups, GroupIndex)
// 			}
// 			if arG != nil {
// 				arG.Delete() // 数据库删除数据
// 				GroupIndex = (GroupIndex + 1)
// 			} else {
// 				break
// 			}
// 		}
// 	}
// 	if lastActId != rankActId {
// 		fmt.Printf("上次排名ID[%d]，本次排名id[%d],不一致", lastActId, rankActId)
// 	} else {
// 		fmt.Printf("上次排名ID[%d]，本次排名id[%d]", lastActId, rankActId)
// 	}
// 	// 没有活动不执行分组
// 	if err != nil || rankActId == -1 {
// 		return
// 	}
// 	fmt.Println("排名活动,id:", rankActId)
// 	//----Func---UserPoint---
// 	CalculateUserPoint := func(u *m.User, ItemCount int64) (point int64) {
// 		// 条件物料获取
// 		nowT := utils.TNow().Unix()
// 		point = 0
// 		point = (point + (u.SlotLv * 10)) // 基准分是老虎机等级的10倍
// 		// 一天的时间戳是86400
// 		var loginOffset int64 = (nowT - u.LastLoginTime)
// 		if loginOffset < 86400 {
// 			point = (point + 10) // 基本等于每天登陆的玩家，增加10关卡的积分
// 		} else if loginOffset < (86400 * 3) {
// 			point = (point + 5) // 3天内有登陆的玩家，增加5关卡积分
// 		}
// 		point = (point + ItemCount) // 最后加上累计获得的道具数量
// 		return point
// 	}
// 	//----Func---FindGroup---
// 	FindGroup := func(point int64, GroupId int64) (groupInfo *m.ActRankGroup) {
// 		// 查询组--这里只保存上层结构，外部调用Update
// 		_, findGroup := arm.RankGroups[GroupId]
// 		if findGroup == false {
// 			newGroup := &m.ActRankGroup{
// 				GroupId:          GroupId,
// 				UserActRankGroup: make(map[string]*m.UserActRank, 0),
// 			}
// 			arm.RankGroups[GroupId] = newGroup
// 			return newGroup
// 		} else {
// 			if len(arm.RankGroups[GroupId].UserActRankGroup) < 30 {
// 				return arm.RankGroups[GroupId]
// 			} else {
// 				var newGroupId int64 = (GroupId + 1)
// 				newGroup := &m.ActRankGroup{
// 					GroupId:          newGroupId,
// 					UserActRankGroup: make(map[string]*m.UserActRank, 0),
// 				}
// 				arm.RankGroups[newGroupId] = newGroup
// 				return newGroup
// 			}
// 		}
// 	}
// 	//----End---
// 	// activeUsers := player.PlayersModule.GetAllPlayers()
// 	activeUsers := make([]*m.User, 0)
// 	// dbmodule.MgoDB.GameDB.FindAllSortLimit("user", nil, nil, &activeUsers, []string{}, 1000)
// 	// err = dbmodule.MgoDB.GameDB.FindAllSortLimit("user", nil, nil, &activeUsers, []string{"-slotLv"}, 10)
// 	dberr := dbmodule.MgoDB.GameDB.FindAll("user", nil, nil, &activeUsers)
// 	if dberr != nil {
// 		log.WithFields(log.Fields{
// 			"method": "ReGroupActRank",
// 		}).Error("获取用户数据失败")
// 		log.Error("ReGroupActRank获取用户数据失败：", err)
// 		return
// 	}

// 	// 先评分，根据用户老虎机登记，和活跃度，给玩家分组
// 	UserAFK := make([]string, 0) // 近似于弃坑玩家
// 	UserPoint := make([]*PointData, 0)
// 	nowT := utils.TNow().Unix()
// 	for _, user := range activeUsers {
// 		if (nowT - user.LastLoginTime) >= (86400 * 7) {
// 			UserAFK = append(UserAFK, user.Uid.Hex()) // 7天未登录，判断为近似弃坑玩家
// 		} else {
// 			// 进度
// 			var totalItemCount int64 = 0
// 			rankProgress, _ := lib.GetOrCreateActProgress(user, rankActId)
// 			if rankProgress != nil {
// 				totalItemCount = rankProgress.TotalItemCount
// 			}
// 			//评分
// 			point := CalculateUserPoint(user, totalItemCount)
// 			newPointData := &PointData{
// 				Uid:       user.Uid.Hex(),
// 				User:      user,
// 				Point:     point,
// 				ItemCount: totalItemCount,
// 			}
// 			// fmt.Printf("活动[%d]玩家 [%s] 活动道具 [%d] \n", rankActId, user.Name, totalItemCount)
// 			if lastActId != rankActId {
// 				newPointData.ItemCount = 0
// 				// fmt.Printf("活动ID不一致，ItemCount重置为0 \n")
// 			}
// 			UserPoint = append(UserPoint, newPointData)
// 		}
// 	}
// 	// 对分数进行排序
// 	sort.Slice(UserPoint, func(i, j int) bool {
// 		return UserPoint[i].Point > UserPoint[j].Point
// 	})
// 	// 后分组
// 	var GroupIndex int64 = 1 // 分组从1索引开始，0是默认值，用于标识新用户
// 	for _, pData := range UserPoint {
// 		group := FindGroup(pData.Point, GroupIndex)
// 		// pData.User.ChangeUserGroup(group.GroupId)
// 		globalFunc.ChangeUserSlotActRankGroup(pData.User.Uid.Hex(), group.GroupId)
// 		// 填写配置--GroupId已在FindGroup赋值
// 		group.ActId = rankActId
// 		group.RewardId = rankRewardId
// 		group.HasRobot = 1
// 		// 新增成员
// 		group.AddMember(&m.UserActRank{
// 			Uid:         pData.Uid,
// 			Name:        pData.User.Name,
// 			Head:        pData.User.Head,
// 			AvatarFrame: pData.User.AvatarFrame,
// 			Item:        pData.ItemCount,
// 			LastRankId:  0,
// 			RankId:      0,
// 			IsRobot:     1,
// 		})
// 		group.Update(group)
// 		arm.RankGroups[group.GroupId] = group
// 		//记录当前组的ID，给下次FindGroup搜索
// 		GroupIndex = group.GroupId
// 	}
// 	// 检测最后一个分组是否已满员，塞机器人
// 	actTurn, _ := lib.GetActTurn(rankActId)
// 	lastGroup, ok := arm.RankGroups[GroupIndex]
// 	if ok {
// 		if len(lastGroup.UserActRankGroup) < 30 {
// 			lastGroup.TryFillUpMemberWithRobot(actTurn, 0)
// 			arm.RankGroups[lastGroup.GroupId] = lastGroup
// 		}
// 	}
// 	// 删除数据库旧的分组数据
// 	GroupIndex = (GroupIndex + 1)
// 	for {
// 		arG := m.GetActRankGroupByGroupId(GroupIndex)
// 		uparG, find := arm.RankGroups[GroupIndex]
// 		if uparG != nil || find {
// 			delete(arm.RankGroups, GroupIndex)
// 		}
// 		if arG != nil {
// 			arG.Delete() // 数据库删除数据
// 			GroupIndex = (GroupIndex + 1)
// 		} else {
// 			break
// 		}
// 	}
// 	// 通知每个分组，自行排序
// 	for _, g := range arm.RankGroups {
// 		g.ReSort("")
// 	}
// }

// 派发活动排名奖励
func (arm *ActRankManager) GiveActRankReward(SendMailFunc func(uid string, title string, content string, resGoods []*m.Goods)) {
	// for _, g := range arm.RankGroups { // 从缓存读取
	// 	g.ReSort()
	// }
	listAccept := make([]*m.ActRankGroup, 0)
	err := dbmodule.MgoDB.GameDB.FindAll(tableName, nil, nil, &listAccept) // 从数据库读取，防止后期新增的组
	if err != nil {
		return
	}
	if len(listAccept) > 0 {
		// 读取奖励表，发放奖励
		rewardId := listAccept[0].RewardId
		rewardList, err := lib.GetActRankRewardList(rewardId)
		if err != nil {
			log.WithFields(log.Fields{
				"method":   "GiveActRankReward",
				"rewardId": rewardId,
			}).Error("没找找到老虎机活动排名配置表")
			return
		}
		if rewardList != nil && len(rewardList) > 0 {
			nowUTCTime := utils.TNow()
			nowZeroUTCTime := utils.ZeroTime(utils.TNow())

			for _, item := range listAccept {
				item.ReSort("") // 通知每个分组，自行排序
				// 记录派奖时间
				if item.SendRewardTimeStamp == nil || len(item.SendRewardTimeStamp) == 0 {
					item.SendRewardTimeStamp = make(map[int64]int64, 0)
				}
				item.SendRewardTimeStamp[nowZeroUTCTime] = nowUTCTime.Unix()
				// 排序后，进行快照
				snapShotErr := item.TakeSnapShot()
				if snapShotErr != nil {
					log.WithFields(log.Fields{
						"method":   "GiveActRankReward",
						"rewardId": rewardId,
						"GroupId":  item.GroupId,
					}).Error(fmt.Sprintf("进行老虎机活动排名快照失败"))
				}
				item.Update(item)
				// 邮件发放奖励
				for uid, rankData := range item.UserActRankGroup {
					if rankData.IsRobot == 1 && rankData.Item > 0 { // 不是机器人,并且,道具数量大于0
						reward, find := rewardList[rankData.RankId]
						if find {
							var mailTitle string = "Activity ranking Award"
							var mailContent string = fmt.Sprintf("Your rank is: %d", rankData.RankId)
							resGoods := make([]*m.Goods, 0)
							if reward.Rewards != nil && len(reward.Rewards) > 0 {
								for _, item := range reward.Rewards {
									resGoods = append(resGoods, &m.Goods{
										Tid: int64(item.Key),
										Num: int64(item.Value),
									})
								}
							}
							SendMailFunc(uid, mailTitle, mailContent, resGoods)
						}
					}
				}
			}
		}
	}
}

// 活动排名存起来，等客户端请求，等客户端领取奖励。
func (arm *ActRankManager) GiveOldActRankReward() {
	listAccept := make([]*m.ActRankGroup, 0)
	err := dbmodule.MgoDB.GameDB.FindAll(tableName, nil, nil, &listAccept) // 从数据库读取，防止后期新增的组
	if err != nil {
		return
	}
	if len(listAccept) > 0 {
		// 读取奖励表，发放奖励
		rewardId := listAccept[0].RewardId
		rewardList, err := lib.GetActRankRewardList(rewardId)
		if err != nil {
			log.WithFields(log.Fields{
				"method":   "GiveActRankReward",
				"rewardId": rewardId,
			}).Error("没找找到老虎机活动排名配置表")
			return
		}
		if rewardList != nil && len(rewardList) > 0 {
			nowUTCTime := utils.TNow()
			nowZeroUTCTime := utils.ZeroTime(utils.TNow())

			for _, item := range listAccept {
				item.ReSort("") // 通知每个分组，自行排序
				// 记录派奖时间
				if item.SendRewardTimeStamp == nil || len(item.SendRewardTimeStamp) == 0 {
					item.SendRewardTimeStamp = make(map[int64]int64, 0)
				}
				item.SendRewardTimeStamp[nowZeroUTCTime] = nowUTCTime.Unix()
				// 排序后，进行快照
				snapShotErr := item.TakeSnapShot()
				if snapShotErr != nil {
					log.WithFields(log.Fields{
						"method":   "GiveActRankReward",
						"rewardId": rewardId,
						"GroupId":  item.GroupId,
					}).Error(fmt.Sprintf("进行老虎机活动排名快照失败"))
				}
				item.Update(item)
				// 邮件发放奖励
				for uid, rankData := range item.UserActRankGroup {
					if rankData.IsRobot == 1 && rankData.Item > 0 { // 不是机器人,并且,道具数量大于0
						reward, find := rewardList[rankData.RankId]
						if find {
							resGoods := make([]m.BaseKV, 0)
							if reward.Rewards != nil && len(reward.Rewards) > 0 {
								for _, item := range reward.Rewards {
									resGoods = append(resGoods, m.BaseKV{
										Key: int64(item.Key),
										Val: int64(item.Value),
									})
								}
							}

							// 保存用户排名
							oldUserActRank := &m.OldUserActRank{
								Uid:        uid,
								RecordTime: nowUTCTime.Unix(),
								GroupId:    item.GroupId,
								ResGoods:   resGoods,
							}
							oldUserActRank.Save()
						}
					}
				}
			}
		}
	}
}

func (arm *ActRankManager) DeleteAllActRank() {

}

// 零点触发的任务
func (arm *ActRankManager) ZeroTimeFunction(SendMailFunc func(uid string, title string, content string, resGoods []*m.Goods)) {
	// 派发活动奖励
	// arm.GiveActRankReward(SendMailFunc)
	// 派发发奖励改为手动领取
	arm.GiveOldActRankReward()
	// 活动排名重新分组--此时如果活动过期了，会删除数据
	arm.ReGroupActRank()
}
